<html>
<head><meta charset="utf-8"><title>Non-Zero Atomics · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Non-Zero.20Atomics.html">Non-Zero Atomics</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="211194126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Non-Zero%20Atomics/near/211194126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Non-Zero.20Atomics.html#211194126">(Sep 24 2020 at 21:51)</a>:</h4>
<p>Anyone has design ideas for Atomic+NonZero types?<br>
Right now I do this by converting back and forth from NonZeroUsize and AtomicUsize example:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">NonZeroUsizeAtomic</span><span class="p">(</span><span class="n">NonZeroUsize</span><span class="p">);</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">NonZeroUsizeAtomic</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">v</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="n">NonZeroUsizeAtomic</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">NonZeroUsize</span>::<span class="n">new</span><span class="p">(</span><span class="n">v</span><span class="p">).</span><span class="n">map</span><span class="p">(</span><span class="n">NonZeroUsizeAtomic</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="k">fn</span> <span class="nf">new_unchecked</span><span class="p">(</span><span class="n">n</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">NonZeroUsizeAtomic</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">Self</span><span class="p">(</span><span class="n">NonZeroUsize</span>::<span class="n">new_unchecked</span><span class="p">(</span><span class="n">n</span><span class="p">))</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">into_inner</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">NonZeroUsize</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">load</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">order</span>: <span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">NonZeroUsize</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="c1">// SAFETY: We never let the user store a raw usize, so it cannot be zero</span>
<span class="w">        </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">NonZeroUsize</span>::<span class="n">new_unchecked</span><span class="p">(</span><span class="n">AtomicUsize</span>::<span class="n">new</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="mf">0.</span><span class="n">get</span><span class="p">()).</span><span class="n">load</span><span class="p">(</span><span class="n">order</span><span class="p">))</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">store</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">val</span>: <span class="nc">NonZeroUsize</span><span class="p">,</span><span class="w"> </span><span class="n">order</span>: <span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">AtomicUsize</span>::<span class="n">new</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="mf">0.</span><span class="n">get</span><span class="p">()).</span><span class="n">store</span><span class="p">(</span><span class="n">val</span><span class="p">.</span><span class="n">get</span><span class="p">(),</span><span class="w"> </span><span class="n">order</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p><a href="https://play.rust-lang.org/?gist=b0ffb323b36bf869d0d4eec998e5f4f5">https://play.rust-lang.org/?gist=b0ffb323b36bf869d0d4eec998e5f4f5</a></p>



<a name="211220239"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Non-Zero%20Atomics/near/211220239" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Non-Zero.20Atomics.html#211220239">(Sep 25 2020 at 05:33)</a>:</h4>
<p>That is not allowed. Atomic operations must use an <code>UnsafeCell</code> to avoid violating aliasing rules. <code>UnsafeCell</code> hides the niche to prevent aliasing issues when matching on something like <code>Option&lt;UnsafeCell&lt;NonZeroUsize&gt;&gt;</code> and at the same time modifying the immer <code>NonZeroUsize</code>.</p>



<a name="211220306"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Non-Zero%20Atomics/near/211220306" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Non-Zero.20Atomics.html#211220306">(Sep 25 2020 at 05:35)</a>:</h4>
<p><a href="https://github.com/rust-lang/rust/issues/68206">https://github.com/rust-lang/rust/issues/68206</a></p>



<a name="211222001"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Non-Zero%20Atomics/near/211222001" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Non-Zero.20Atomics.html#211222001">(Sep 25 2020 at 06:17)</a>:</h4>
<p>We could have <code>AtomicOptionNonZeroUsize</code>, but that can be put in some 3rd party crate easy enough.</p>



<a name="211242779"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Non-Zero%20Atomics/near/211242779" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Non-Zero.20Atomics.html#211242779">(Sep 25 2020 at 10:51)</a>:</h4>
<p>Yeah, basically mixing enum layout optimization and atomics ops is not a a good idea. Maybe with a future <code>#[repr(atomic)]</code> annotation to require the discriminant be determined using atomic loads it could be fine, but even then it's just better to hand-roll the layout optimization using your own newtype wrapper, as <span class="user-mention" data-user-id="224471">@Lokathor</span> suggested</p>



<a name="211249559"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Non-Zero%20Atomics/near/211249559" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Non-Zero.20Atomics.html#211249559">(Sep 25 2020 at 12:12)</a>:</h4>
<p>I'm trying to decide if my example also inhibit unsoundness under <code>Option</code> I don't think it should? writing into an outer Option here would require holding a unique reference, (and there is no unsafe here)</p>



<a name="211278385"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Non-Zero%20Atomics/near/211278385" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Non-Zero.20Atomics.html#211278385">(Sep 25 2020 at 16:08)</a>:</h4>
<p>The problem is not <em>writing</em>, but <em>reading</em> the discriminant:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">AtomicNonZero</span>::<span class="n">new</span><span class="p">(</span><span class="mi">42</span><span class="p">).</span><span class="n">unwrap</span><span class="p">());</span><span class="w"></span>
::<span class="n">crossbeam</span>::<span class="n">thread</span>::<span class="n">scope</span><span class="p">(</span><span class="o">|</span><span class="n">scope</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">scope</span><span class="p">.</span><span class="n">spawn</span><span class="p">(</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">inner</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">inner</span><span class="p">.</span><span class="n">store</span><span class="p">(</span><span class="o">..</span><span class="p">.);</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">scope</span><span class="p">.</span><span class="n">spawn</span><span class="p">(</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nb">drop</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">is_some</span><span class="p">());</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">);</span><span class="w"> </span><span class="c1">// &lt;- non-atomic read to check against 0 =&gt; data race =&gt; UB</span>
<span class="p">}).</span><span class="n">unwrap</span><span class="p">();</span><span class="w"></span>
</code></pre></div>



<a name="211351498"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Non-Zero%20Atomics/near/211351498" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Non-Zero.20Atomics.html#211351498">(Sep 26 2020 at 09:28)</a>:</h4>
<p>In case no one else noticed my example makes 0 sense and doesn't do anything LOL<br>
I shouldn't be allowed to post on Zulip at 1AM</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>